﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace RedmineWorkerDotNET.App.Classes
{
    public class UIConfigSaver
    {
        public delegate void OnLoadHandler(WindowPositionSettings objSettings);
        public delegate void OnSaveHandler(WindowPositionSettings objSettings);

        #region Static Methods

        public static UIConfigSaver AttachPositionerToForm(Form frmDialog)
        {
            XmlConfiguration objConfigurationInfo = new XmlConfiguration(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "dialogs.xml"));
            UIConfigSaver objPositioner = new UIConfigSaver(objConfigurationInfo, frmDialog);
            return objPositioner;
        }

        public static UIConfigSaver AttachPositionerToForm(Form frmDialog, OnLoadHandler evExtraEventOnLoad, OnSaveHandler evExtraEventOnSave)
        {
            XmlConfiguration objConfigurationInfo = new XmlConfiguration(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "dialogs.xml"));
            UIConfigSaver objPositioner = new UIConfigSaver(objConfigurationInfo, frmDialog, evExtraEventOnLoad, evExtraEventOnSave);
            return objPositioner;
        }

        #endregion

        #region Attributes

        private XmlConfiguration _objAppSettings;
        private WindowPositionSettings _objPositionSettings;

        private OnLoadHandler _evExtraEventOnLoad = null;
        private OnSaveHandler _evExtraEventOnSave = null;

        #endregion

        #region Initialization

        private UIConfigSaver(XmlConfiguration objAppSettings, Form frmDialog)
        {
            _objAppSettings = objAppSettings;
            _objPositionSettings = new WindowPositionSettings(_objAppSettings, frmDialog.GetType().Name);

            frmDialog.Load += new EventHandler(frmDialog_Load);
            frmDialog.FormClosing += new FormClosingEventHandler(frmDialog_FormClosing);
        }

        private UIConfigSaver(XmlConfiguration objAppSettings, Form frmDialog, OnLoadHandler evExtraEventOnLoad, OnSaveHandler evExtraEventOnSave)
        {
            _objAppSettings = objAppSettings;
            _objPositionSettings = new WindowPositionSettings(_objAppSettings, frmDialog.GetType().Name);

            frmDialog.Load += new EventHandler(frmDialog_Load);
            frmDialog.FormClosing += new FormClosingEventHandler(frmDialog_FormClosing);

            _evExtraEventOnLoad = evExtraEventOnLoad;
            _evExtraEventOnSave = evExtraEventOnSave;
        }

        #endregion

        private void frmDialog_Load(object sender, EventArgs e)
        {
            Form frmDialog = (Form)sender;

            try
            {
                if (_objPositionSettings.AreSettingsEmpty())
                {
                    frmDialog.StartPosition = FormStartPosition.CenterScreen;
                    return;
                }

                frmDialog.StartPosition = FormStartPosition.Manual;
                frmDialog.Top = (int)_objPositionSettings.Top;
                frmDialog.Left = (int)_objPositionSettings.Left;
                frmDialog.Height = (int)_objPositionSettings.Height;
                frmDialog.Width = (int)_objPositionSettings.Width;

                // Very quick and dirty - but it does the job
                if (_objPositionSettings.Maximized)
                {
                    frmDialog.WindowState = FormWindowState.Maximized;
                }

                if (_evExtraEventOnLoad != null)
                    _evExtraEventOnLoad(_objPositionSettings);
            }
            catch (Exception excError)
            {
                // TODO Handle error
            }
        }

        private void frmDialog_FormClosing(object sender, FormClosingEventArgs e)
        {
            Form frmDialog = (Form)sender;

            try
            {
                _objPositionSettings.Top = frmDialog.Top;
                _objPositionSettings.Left = frmDialog.Left;
                _objPositionSettings.Height = frmDialog.Height;
                _objPositionSettings.Width = frmDialog.Width;

                _objPositionSettings.Maximized = (frmDialog.WindowState == FormWindowState.Maximized);

                if (_evExtraEventOnSave != null)
                    _evExtraEventOnSave(_objPositionSettings);

                _objPositionSettings.Save();

                frmDialog.Load -= new EventHandler(frmDialog_Load);
                frmDialog.FormClosing -= new FormClosingEventHandler(frmDialog_FormClosing);
            }
            catch (Exception excError)
            {
                // TODO Handle error
            }
        }

        public WindowPositionSettings CurrentPosition
        {
            get { return _objPositionSettings; }
        }

        #region Window Settings

        public class WindowPositionSettings
        {
            private XmlConfiguration _objSettings;
            private string _sWindowName;

            internal WindowPositionSettings(XmlConfiguration objSettings, string sWindowName)
            {
                _objSettings = objSettings;
                _sWindowName = sWindowName.ToLower();
            }

            public Boolean AreSettingsEmpty()
            {
                return Width == 0;
            }

            internal void Read()
            {
                _objSettings.Read();
            }

            internal void Save()
            {
                _objSettings.Save();
            }

            public string GetProperty(string sPropertyName)
            {
                return _objSettings.GetStringSetting(_sWindowName + "_" + sPropertyName, String.Empty);
            }

            public void SetProperty(string sPropertyName, object objValue)
            {
                _objSettings.SetSetting(_sWindowName + "_" + sPropertyName, objValue.ToString());
            }

            public double Top
            {
                get
                {
                    double dValue = 0;
                    Double.TryParse(GetProperty("top"), out dValue);
                    return dValue;
                }
                internal set { SetProperty("top", value.ToString()); }
            }

            public double Left
            {
                get
                {
                    double dValue = 0;
                    Double.TryParse(GetProperty("left"), out dValue);
                    return dValue;
                }
                internal set { SetProperty("left", value.ToString()); }
            }

            public double Height
            {
                get
                {
                    double dValue = 0;
                    Double.TryParse(GetProperty("height"), out dValue);
                    return dValue;
                }
                internal set { SetProperty("height", value.ToString()); }
            }

            public double Width
            {
                get
                {
                    double dValue = 0;
                    Double.TryParse(GetProperty("width"), out dValue);
                    return dValue;
                }
                internal set { SetProperty("width", value.ToString()); }
            }

            public Boolean Maximized
            {
                get
                {
                    Boolean bValue = false;
                    Boolean.TryParse(GetProperty("maximized"), out bValue);
                    return bValue;
                }
                internal set { SetProperty("maximized", value.ToString()); }
            }
        }

        #endregion
    }
}
